using System;
using System.Collections.Generic;
using System.Text;
using MbUnit.Framework;

using SqlBlocks;

namespace Tests
{
    [TestFixture("Various migration operations")]
    [Author("Kurt Mackey", "kurt@mubble.net")]
    [FixtureCategory("Migrations")]
    [Importance(TestImportance.Critical)]
    public abstract class Migrations
    {
        protected abstract SqlBlocks.Drivers.IDatabaseDriver Driver { get; }
        protected abstract string ConnectionString { get; }

        /// <summary>
        /// This test should return a database version greater than or equal to 0
        /// </summary>
        [Test("Tests database initialization.")]
        public void DatabaseInit()
        {
            double version = this.Driver.CheckVersion(this.ConnectionString);
            Assert.AreEqual(0, version);
        }

        //[Test("Tests table creation")]
        //public void CreateTable()
        //{
        //    Changeset db = new Changeset();

        //    db.CreateTable("TestItems", StandardPrimaryKeyType.Int)
        //        .AddColumn<string>("Name");

        //    this.Driver.Commit(db, 1);

        //    db = new Changeset();
        //    db.RunSql("SELECT ID, Name FROM TestItems");

        //    this.Driver.Commit(db, 2);
        //}

        //[Test("Tests unique index creation")]
        //public virtual void CreateTableWithUniqueIndex()
        //{
        //    Changeset db = new Changeset();

        //    Table t = db.CreateTable("TestUniqueIndex", StandardPrimaryKeyType.Int);
        //    Column c = t.AddColumn<string>("Name");

        //    Index i = t.CreateIndex("Name").Unique();
        //    this.Driver.Commit(db, 3);
        //}

        [Test("Tests a known bad migration")]
        [ExpectedException(typeof(SqlBlocks.MigrationFailedException))]
        public virtual void FailMigration()
        {
            double currentVersion = this.Driver.CheckVersion(this.ConnectionString);

            Changeset db = new Changeset();
            db.RunSql("CREATE TABLE ThisTableShouldNeverGetCreated (id int NOT NULL)");

            db.RunSql("SELECT blah, bloo, bleat FROM NonExistantSheepleTable");

            try
            {
                this.Driver.Commit(db, currentVersion + 1);
            }
            catch { }

            Assert.AreEqual(currentVersion, this.Driver.CheckVersion(this.ConnectionString));

            db = new Changeset();
            db.RunSql("SELECT * FROM ThisTableShouldNeverGetCreated");
            
            //This should fail
            this.Driver.Commit(db, currentVersion + 2);
        }

        [SetUp("Sets up the driver for testing")]
        public abstract void SetupDriver();

        [TearDown("Tears down the driver")]
        public abstract void TeardownDriver();
    }
}
